package com.xyzq.cgate.core.plugin.pre;

import com.google.common.util.concurrent.RateLimiter;
import com.xyzq.cgate.common.constant.Constants;
import com.xyzq.cgate.common.enums.PluginDetailEnum;
import com.xyzq.cgate.common.rule.custom.entity.ComplexRule;
import com.xyzq.cgate.core.cache.CacheManager;
import com.xyzq.cgate.core.component.ratelimiter.RateLimiterFactory;
import com.xyzq.cgate.core.plugin.AbstractPlugin;
import com.xyzq.cgate.core.plugin.IPluginChain;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Description:
 * @author chenchen
 * @date 2019/6/26 15:31
 */
public class GrayReleasePlugin extends AbstractPlugin {

    private static final Logger LOGGER = LoggerFactory.getLogger(SignPlugin.class);

    private final CacheManager cacheManager;

    public GrayReleasePlugin(final CacheManager cacheManager) {
        super(cacheManager);
        this.cacheManager = cacheManager;
    }

    @Override
    protected Mono<Void> doExecute(ServerWebExchange exchange, IPluginChain chain, ComplexRule rule) {
        InetSocketAddress remoteAddress = exchange.getRequest().getRemoteAddress();
        String clientIp = Objects.requireNonNull(remoteAddress).getAddress().getHostAddress();
        if(StringUtils.isNotBlank(clientIp)) {
            boolean present = Arrays.stream(rule.getGrayRelease().getIps())
                    .filter(ip -> StringUtils.equalsIgnoreCase(ip, clientIp))
                    .findFirst()
                    .isPresent();
            if(present) {
                exchange.getAttributes().put(Constants.GRAY_RELEASE_LOADBALANCE, rule.getGrayRelease().getServer());
            }
        }
        return chain.execute(exchange);
    }

    @Override
    public String getPluginPhase() {
        return PluginDetailEnum.RATELIMITER.getPhase();
    }

    @Override
    public int getCode() {
        return PluginDetailEnum.RATELIMITER.getCode();
    }

    @Override
    public String getName() {
        return PluginDetailEnum.RATELIMITER.getName();
    }
}
